home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-07-30 | 28.7 KB | 1,111 lines |
- #!/bin/sh
- #DEBUG
- #errlog=/var/spool/lp/log # lp spooler error log file
- #exec 2>> $errlog
-
- #
- #**************************************************************************
- #*
- #* Copyright (c) 1993 Silicon Graphics, Inc.
- #* All Rights Reserved
- #*
- #* RESTRICTED RIGHTS LEGEND:
- #*
- #* Use, duplication or disclosure by the Government is subject to
- #* restrictions as set forth in subdivision (c)(1)(ii) of the Rights in
- #* Technical Data and Computer Software clause at DFARS 52.227-7013,
- #* and/or in similar or successor clauses in the FAR, DOD or NASA FAR
- #* Supplement. Unpublished - rights reserved under the Copyright Laws of
- #* the United States. Contractor is SILICON GRAPHICS, INC., 2011 N.
- #* Shoreline Blvd., Mountain View, CA 94039-7311
- #**************************************************************************
- #*
- #* File: lputil
- #*
- #* $Revision: 1.67 $
- #*
- #* Description:
- #* Printer utility script for use by administration tools.
- #*
- #* This script is used by higher level commands and scripts to perform
- #* lp system administration. This script handles adding, deleting,
- #* removing and typing of printers.
- #*
- #**************************************************************************
-
- # Make sure we have a sane umask so that lp can read files we create
-
- umask 022
-
- # Reset path since we might spawn daemons
-
- PATH=/usr/bsd:/bin:/usr/bin:/usr/sbin:/etc:/usr/etc
-
- # Directories
-
- X11_DIR=/usr/lib/X11
- OLD_SPOOL_DIR=/usr/spool/lp # For 4.0 compatibility
- SPOOL_DIR=/var/spool/lp # New location in 5.0
- REMOTE_MEMBER_DIR=$OLD_SPOOL_DIR/member # For 4.0 compatibility
- REMOTE_INTER_DIR=$OLD_SPOOL_DIR/interface
- REMOTE_INTERGUI_DIR=$OLD_SPOOL_DIR/gui_interface
- REMOTE_APP_DEFS_DIR=$X11_DIR/app-defaults
- REMOTE_LANG_APP_DIR=$X11_DIR/$LANG/app-defaults
- POD_DIR=$SPOOL_DIR/pod
- MEMBER_DIR=$SPOOL_DIR/member
- MODELGUI_DIR=$SPOOL_DIR/gui_model
- INTERGUI_DIR=$SPOOL_DIR/gui_interface
- SETTINGS_DIR=$SPOOL_DIR/settings
- DATA_DIR=/usr/lib/print/data
- ACTIVEICON_DIR=$SPOOL_DIR/activeicons
- SPOOL_APP_DEFS_DIR=$SPOOL_DIR/app-defaults
- PSRIP_PARAMS_DIR=$SPOOL_DIR/psparams
- PRINT_DIR=/usr/lib/print
- SETDEVPERMS=$PRINT_DIR/setdevperms
-
- PPD_MODEL_NAME=impressario_ppd_model
- PPD_MODEL_DIR=$SPOOL_DIR/PPD_model
- PPD_TO_POD=/usr/lib/print/ppdtopod
- PPD_PACK_FILES=/usr/lib/print/packppdfiles
- HAVE_PPD=0
- NUM_PPD_COLORS=1
- PPD_3COLOR=$SPOOL_DIR/PPD_model/impressario_ppd_common_3color.ppd
- PPD_4COLOR=$SPOOL_DIR/PPD_model/impressario_ppd_common_4color.ppd
-
- # Global variables
-
- REMOTE_LOGIN_ID=lp
- ACTIVEICON_TEMPLATE_FILENAME=$DATA_DIR/activeicon_template
-
- #Binaries
-
- UPDATE_IOPERM=/usr/lib/print/lpioupdate
-
- #
- # This routine catches the return exit code of the previous command
- # and exits if there was any trouble.
- #
- rcexit()
- {
- rc=$?
- if [ $rc != 0 ]; then # exit with an error code
- exit $rc # if the command failed
- fi
- }
-
- #
- # See if the number of installed printers is one
- # If so, make it the default printer
- #
-
- selectSoloPrinterAsDefault() {
- q="` lpstat -s | grep device | wc -l"
- if [ $q = 1 ]; then
- "` /usr/lib/lpadmin -d$nam"
- fi
- }
-
- #
- # This routine will create the file which is recognized by the desktop
- # as an active icon, and call tagprinter to put the right tag on it.
- #
- create_activeicon()
- {
- # If we have no type, then give up and return
- #
- if [ "$rt" = "" ]; then
- return 0
- fi
-
- # If the icon directory doesn't exist, give up and return.
- #
- if [ ! -d $ACTIVEICON_DIR ]; then
- return 0
- fi
-
- # If the activeicon template file doesn't exist, give up and return.
- #
- if [ ! -f $ACTIVEICON_TEMPLATE_FILENAME ]; then
- return 0
- fi
-
- # First thing: install the activeicon file for printer $nam.
- #
- cp $ACTIVEICON_TEMPLATE_FILENAME $ACTIVEICON_DIR/$nam > /dev/null 2>&1
-
- # Make sure lp can write the file so it can tag it.
- #
- chown lp.lp $ACTIVEICON_DIR/$nam > /dev/null 2>&1
-
- # Set some defines to make tagging easier.
- # The base (type of printer) tags
- #
- Dumb=66048 # 0x10200
- DumbColor=66080 # 0x10220
- Raster=66112 # 0x10240
- ColorRaster=66144 # 0x10260
- Plotter=66176 # 0x10280
- PostScript=66208 # 0x102A0
- ColorPostScript=66240 # 0x102C0
- MonoPostScript=66272 # 0x102E0
-
- # And now the state modifiers for those type tags:
- #
- Networked=8 # 0x8
-
- # Set tag template based on printer type:
- # Parse printer type and set the basetag.
- #
- case $rt in
- Dumb|DUMB|dumb)
- printertype=$Dumb
- ;;
- DumbColor|DUMBCOLOR|dumbcolor|Color|COLOR|color)
- printertype=$DumbColor
- ;;
- Raster|RASTER|raster)
- printertype=$Raster
- ;;
- ColorRaster|COLORRASTER|colorraster)
- printertype=$ColorRaster
- ;;
- Plotter|PLOTTER|plotter)
- printertype=$Plotter
- ;;
- PostScript|POSTSCRIPT|postscript)
- printertype=$PostScript
- ;;
- ColorPostScript|COLORPOSTSCRIPT|colorpostscript)
- printertype=$ColorPostScript
- ;;
- MonoPostScript|MONOPOSTSCRIPT|monopostscript)
- printertype=$MonoPostScript
- ;;
- *) # XXX we just die silently if there's an unrecognized type.
- # this is ok since we wouldn't know what to tag it anyways.
- return 0
- ;;
- esac
-
- # If we're a remote printer, add the "networked" modifier onto the tag
- #
- if [ -n "$rh" ]; then
- printertype=`expr $printertype + $Networked`
- fi
-
- /usr/lib/print/tagprinter $nam $printertype > /dev/null 2>&1
-
- return 0
- }
-
-
- #
- # This routine will install the printer icons on the desktop
- #
- install_icon()
- {
- # OK, first create the installed printer active icon file
- # which will be installed into the desktop.
- #
- create_activeicon
-
- return 0
- }
-
- #
- # This function creates a number of printing support directories
- #
- create_support_dirs()
- {
- # Create a printer options settings directory for the printer
- #
- if [ ! -d "$SETTINGS_DIR" ]; then
- mkdir -p $SETTINGS_DIR
- chmod 755 $SETTINGS_DIR
- chown lp.sys $SETTINGS_DIR
- fi
- if [ ! -d "$SETTINGS_DIR/$nam" ]; then
- mkdir $SETTINGS_DIR/$nam
- chmod 1777 $SETTINGS_DIR/$nam
- chown lp.sys $SETTINGS_DIR/$nam
- fi
-
- # Create a graphical options interface directory
- #
- if [ ! -d "$INTERGUI_DIR" ]; then
- mkdir -p $INTERGUI_DIR
- chmod 755 $INTERGUI_DIR
- chown lp.sys $INTERGUI_DIR
- fi
- if [ ! -d "$INTERGUI_DIR/ELF" ]; then
- mkdir $INTERGUI_DIR/ELF
- chmod 755 $INTERGUI_DIR/ELF
- chown lp.sys $INTERGUI_DIR/ELF
- fi
-
- # Create a POD directory
- #
- if [ ! -d "$POD_DIR" ]; then
- mkdir -p $POD_DIR
- chmod 755 $POD_DIR
- chown lp.sys $POD_DIR
- fi
-
- return 0
- }
-
-
- #
- # This function installs the Printer Option Panel program
- # (a.k.a. graphical model file) if it is available
- #
- install_guimodel()
- {
- # First install the gui model program
-
- # If this is a network printer we copy the graphical options
- # panel from the host gui interface dir to the client
- # interface dir. We save some space by linking the program
- # if the client and server are the same machine.
- #
- if [ -n "$rh" ]; then
- if [ "$rh" = "`/usr/bsd/hostname`" ]; then
- if [ -x $INTERGUI_DIR/ELF/$rp.gui ]; then
- ln -s $INTERGUI_DIR/ELF/$rp.gui $INTERGUI_DIR/ELF/$nam.gui
- fi
- if [ -x $INTERGUI_DIR/$rp.gui ]; then
- ln -s $INTERGUI_DIR/$rp.gui $INTERGUI_DIR/$nam.gui
- fi
- else
- rcp $REMOTE_LOGIN_ID@$rh:$REMOTE_INTERGUI_DIR/ELF/$rp.gui \
- $INTERGUI_DIR/ELF/$nam.gui 2>/dev/null
- if [ $? -ne 0 ]; then
- rcp $REMOTE_LOGIN_ID@$rh:$REMOTE_INTERGUI_DIR/$rp.gui \
- $INTERGUI_DIR/$nam.gui 2>/dev/null
- fi
- fi
- else
- # If the printer is local make links instead of copying,
- # to save some space.
- #
- if [ -x $MODELGUI_DIR/ELF/$mod.gui ]; then
- ln -s $MODELGUI_DIR/ELF/$mod.gui $INTERGUI_DIR/ELF/$nam.gui
- else
- if [ "$HAVE_PPD" = "1" ]; then
- # For PPD there may not be a PPD name $nam.gui since we have
- # a general purpose PPD GUI that works for many GUIs.
- # Use this if a specific PPD GUI is not found
- if [ -x $MODELGUI_DIR/ELF/$PPD_MODEL_NAME.gui ]; then
- ln -s $MODELGUI_DIR/ELF/$PPD_MODEL_NAME.gui \
- $INTERGUI_DIR/ELF/$nam.gui
- fi
- fi
-
- fi
- fi
-
- # Now install the app-defaults
-
- # If this is a network printer we need to copy the graphical
- # options panel app-defaults file to the spooling system
- # app-defaults subdir.
- #
- if [ -n "$rh" ]; then
- # Parse the interface file on the remote machine for the
- # class name of the options panel.
- #
- guiclass=`rsh $rh -n -l $REMOTE_LOGIN_ID \
- "/bin/sh -c \"egrep '^GUI_CLASS' $REMOTE_INTER_DIR/$rp\"" \
- 2>/dev/null`
- if [ \( $? -eq 0 \) -a \( -n "$guiclass" \) ]; then
- guiclass=`expr "$guiclass" : '^GUI_CLASS=\(.*\)'`
-
- # If we have a GUI class name...
- #
- if [ -n "$guiclass" ]; then
- # Create the app-defaults subdir
- #
- if [ ! -d "$SPOOL_APP_DEFS_DIR" ]; then
- mkdir -p $SPOOL_APP_DEFS_DIR
- chmod 755 $SPOOL_APP_DEFS_DIR
- chown lp.sys $SPOOL_APP_DEFS_DIR
- fi
- if [ ! -d "$SPOOL_APP_DEFS_DIR/$nam" ]; then
- mkdir $SPOOL_APP_DEFS_DIR/$nam
- chmod 755 $SPOOL_APP_DEFS_DIR/$nam
- chown lp.sys $SPOOL_APP_DEFS_DIR/$nam
- fi
-
- # Copy the app-defaults file from the remote host
- # to the spooler app-defaults subdir. Note that
- # if LANG is set and is something other than "C"
- # we copy over that app-default file.
- #
- apprcp=1
- if [ \( "$LANG" != "" \) -a \( "$LANG" != "C" \) ]; then
- rcp $REMOTE_LOGIN_ID@$rh:$REMOTE_LANG_APP_DIR/$guiclass \
- $SPOOL_APP_DEFS_DIR/$nam/$guiclass 2>/dev/null
- apprcp=$?
- fi
- if [ $apprcp -ne 0 ]; then
- rcp $REMOTE_LOGIN_ID@$rh:$REMOTE_APP_DEFS_DIR/$guiclass \
- $SPOOL_APP_DEFS_DIR/$nam/$guiclass 2>/dev/null
- fi
- fi
- fi
- fi
-
- return 0
- }
-
-
- #
- # This function installs the POD files. It is the caller's responsibilty
- # to ensure that the printer is local
- #
- install_pod()
- {
- # Install the POD files for a local printer. Notice that we
- # do a straight copy of the status and log files but the config
- # file is copied by nawk which edits the 'Port Path' entry to
- # contain the device port pathname. We also handle some special
- # files for PPD drivers here.
- #
- if [ -d $DATA_DIR ]; then
-
- if [ "$HAVE_PPD" = "1" ]; then
-
- # PPD file.
- if [ -d $PPD_MODEL_DIR ]; then
-
- # Parse the PPD file and build the POD
- # files on the fly since the features of the printer vary
- # (the POD file describes the printer's features).
-
- if [ -x $PPD_TO_POD ]; then
- $PPD_TO_POD $mod $PPD_MODEL_DIR/$ppd_name
- rcexit
- fi
-
- # We add our own general purpose options for PPD drivers.
- # This varies if the pritner is a monochrome, 3 color (rgb),
- # or four color device. Default is monochrome. If it is
- # 3 or 4 create a link in /var/spool/lp/PPD_model to
- # impressario_ppd_common_3color.ppd or
- # impressario_ppd_common_4color.ppd. The linked file is
- # "<ppdname>.extension.ppd" which packppdfiles will know
- # to use.
-
- if [ "$NUM_PPD_COLORS" != "1" ]; then
- name="`echo "$ppd_name" | sed 's/\.ppd/\.extension\.ppd/'`"
- if [ ! -f $PPD_MODEL_DIR/$name ]; then
- if [ "$NUM_PPD_COLORS" = "3" ]; then
- if [ -f $PPD_3COLOR ]; then
- ln -s $PPD_3COLOR $PPD_MODEL_DIR/$name
- fi
- else
- if [ -f $PPD_4COLOR ]; then
- ln -s $PPD_4COLOR $PPD_MODEL_DIR/$name
- fi
- fi
- fi
-
- fi
-
- # This code creats the ~lp/app-defaults/<printername> file
- # for PPDs. Differs from other in that it contains PPDs
- # and resource files all packed together. They are unpacked
- # by the PPD GUI. We do this because 5.3 clients only copy
- # over one file and we have to "pack" in the PPD files
- # to get them over to the 5.3 client.
-
- if [ -x $PPD_PACK_FILES ]; then
-
- # Create working dir because packppdfiels won't.
-
- if [ ! -d "$SPOOL_APP_DEFS_DIR/$nam" ]; then
- mkdir $SPOOL_APP_DEFS_DIR/$nam
- chmod 755 $SPOOL_APP_DEFS_DIR/$nam
- chown lp.sys $SPOOL_APP_DEFS_DIR/$nam
- fi
-
- $PPD_PACK_FILES $ppd_name $nam
- rcexit
- fi
-
- fi
- fi
-
- if [ -f $DATA_DIR/$mod.status ]; then
- cp $DATA_DIR/$mod.status $POD_DIR/$nam.status 2>/dev/null
- rcexit
- chown lp.lp $POD_DIR/$nam.status
- chmod 0644 $POD_DIR/$nam.status
- fi
- if [ -f $DATA_DIR/$mod.config ]; then
- nawk -F\| '{
- if ($1 ~ /^[ ]*Port[ ]+Path/) {
- printf("%s| %s\n", $1, portdev)
- } else {
- printf("%s\n", $0)
- }
- }' portdev=$dev $DATA_DIR/$mod.config > \
- $POD_DIR/$nam.config 2>/dev/null
- rcexit
- chown lp.lp $POD_DIR/$nam.config
- chmod 0644 $POD_DIR/$nam.config
- fi
- if [ -f $DATA_DIR/$mod.log ]; then
- cp $DATA_DIR/$mod.log $POD_DIR/$nam.log 2>/dev/null
- rcexit
- chown lp.lp $POD_DIR/$nam.log
- chmod 0644 $POD_DIR/$nam.log
- fi
- fi
-
- return 0
- }
-
-
- #
- # Remove the active icon file for a printer. This is separated from
- # remove_impressario because when changing connection (lputil replace)
- # the printer manager gets really messed up if the icon is removed.
- #
- remove_activeicon()
- {
- # Remove the active icon.
- #
- rm -f $ACTIVEICON_DIR/$nam
- }
-
- #
- # Change the permissions on the device as specified in the config file.
- # We do this because SCSI printers have fake devices for lpsched to
- # open, but actually use a different device for printing. This whole
- # mess should be fixed.
- #
- fix_real_device()
- {
- if [ -f $POD_DIR/$nam.config ]
- then
- real_device=`nawk -F\| '/^[ ]*Port[ ]+Path/ {
- if (match($2, /[^ ]+/)) {
- device = substr($2, RSTART, RLENGTH);
- printf("%s", device);
- }
- exit
- }' $POD_DIR/$nam.config 2>/dev/null`
-
- # If the printer was local and there are no other printers
- # connected to this port, change the owner to root.sys and
- # the permissions to defaults they are shipped with.
-
- if [ -n "$real_device" -a "$real_device" != "$dev" ]
- then
- mv $POD_DIR/$nam.config $POD_DIR/$nam.configtemp
- grep "$real_device" $POD_DIR/*.config > /dev/null 2>&1
- if [ $? != 0 ]; then
- chmod 0600 $real_device
- chown root.sys $real_device
- #Update /etc/ioperms file by remving entry (see ioconfig(1M))
- $SETDEVPERMS -d "$real_device 0600 lp sys"
- fi
- mv $POD_DIR/$nam.configtemp $POD_DIR/$nam.config
- fi
- fi
- }
-
- #
- # This routine would remove the GUI interface files and
- # printer database file while removing an existing printer.
- #
- remove_impressario()
- {
- # Remove the printer options settings directory
- #
- rm -rf $SETTINGS_DIR/$nam
-
- # Remove the graphical options panel
- #
- rm -f $INTERGUI_DIR/ELF/$nam.gui
- rm -f $INTERGUI_DIR/$nam.gui
-
- # Remove the graphical options panel app-defaults
- #
- rm -rf $SPOOL_APP_DEFS_DIR/$nam
-
- # Remove the POD files
- #
- if [ -d $POD_DIR ]; then
- fix_real_device
- rm -f $POD_DIR/$nam.status
- rm -f $POD_DIR/$nam.config
- rm -f $POD_DIR/$nam.log
- fi
-
- # Remove the psrip paramaters directory for the printer
- #
- if [ -d $PSRIP_PARAMS_DIR/$nam ]; then
- rm -rf $PSRIP_PARAMS_DIR/$nam
- fi
-
- return 0
-
- }
-
- #
- # Remove a printer, including all the impressario stuff.
- #
- remove_printer()
- {
- nam=$1
- # Cancel any outstanding print requests
- #
- cancel `lpstat -o$nam | awk '{ print $1 }'` >/dev/null 2>&1
-
- # Get the device pahtname from the member file
- #
- dev=`cat $MEMBER_DIR/$nam 2> /dev/null`
-
- # Remove the printer
- #
- /usr/lib/lpadmin -x$nam
- rc=$?
-
- if [ "$rc" != 0 ]; then
- exit $rc
- fi
-
- # If the printer was local and there are no other printers
- # connected to this port, change the owner to root.sys and
- # the permissions to defaults they are shipped with.
- #
- if [ \( -n "$dev" \) -a \( "$dev" != "/dev/null" \) ]; then
- grep "$dev" $MEMBER_DIR/* > /dev/null 2>&1
- if [ $? != 0 ]; then
- chmod 0666 $dev
- chown root.sys $dev
- # For 6.4+ update /etc/ioperms file (see ioconfig(1M)) by
- # removing this line
- $SETDEVPERMS -d "$dev 0600 lp sys"
- fi
- fi
-
- # Old style printers had "/dev/printername" linked to their
- # device.
- #
- if [ -f /dev/$nam ]; then
- rm -f /dev/$nam
- fi
-
- # Remove all the Impressario files.
- #
- remove_impressario
- remove_activeicon
- }
-
- #
- # Trap handler for when we have a problem installing
- #
- install_error()
- {
- set +e
- trap '' 0 1 2 3 15
- echo "Error installing printer '$1'" 1>&2
- remove_printer $1
- exit 1
- }
-
- #
- # This routine will install the GUI model files and printer
- # database files while adding a new printer.
- #
- install_impressario()
- {
- # If anything goes wrong with impr stuff, abort
- set -e
- trap 'install_error $nam' 0 1 2 3 15
-
- # Now install the printer's active icon in the desktop.
- #
- install_icon
-
- # Create the printing support directories
- #
- create_support_dirs
-
- # If the printer is local install the POD files
- #
- if [ -z "$rh" ]; then
- install_pod
- fi
-
- #
- # Remove error handling, because install_guimodel uses non-zero
- # exit status to test existence of remote gui modelf files. That
- # code shouldn't ever be used anymore because of the "addnet"
- # command, but it's still there so it should still work
- #
-
- set +e
- trap '' 0 1 2 3 15
-
- # Install the graphical options panel
- #
- install_guimodel
-
- return 0
- }
-
- #########################################################################
- #
- # Main program
- #
-
- #
- # Start in a base directory
- #
- cd $SPOOL_DIR
-
- #
- # Pick the primary function we are to perform
- #
- case $1 in
- getinfo)
- #
- # getinfo <printername>
- #
- # This option is used to find various pieces of information
- # about an installed printer. The output format is multilple
- # lines of keyword / value pairs separated by "="
- #
- shift
- nam=$1
- if [ -z "$nam" ]; then
- echo "No printer name was specified." 1>&2
- exit 1
- fi
- i=$nam
- if [ -r class/$i ]; then
- # If <printername> is a class, use the first member of the class.
- #
- i=`line < class/$i`
- fi
- cd interface
- if [ ! -f $i ]; then
- echo "non-existent" 1>&2
- exit 2
- else
- egrep \
- "^NAME=|^TYPE=|^HOSTNAME=|^HOSTPRINTER=|^BAUDRATE=|^STTYPARAMS=" $i
- exit $?
- fi
- ;;
- list)
- /usr/lib/print/modelinfo
- ;;
- replacenet|addnet)
- delete=1;
- if [ "$1" = "replacenet" ]; then
- delete=0
- fi
- #
- # Add a networked printer
- #
- # addnet <host> <printer> <name> [<nettype>]
- host=$2
- printer=$3
- nam=$4
- type=
- if [ $# -gt 4 ]; then
- type="-t $5"
- fi
- # Install or replace the printer. Installing a printer
- # overwrites any printer or class with the same name. It is
- # the caller's responsibility to check for duplicate names.
- #
- # Replacing a printer changes the device and model for a
- # printer, but doesn't blow away the queue.
- #
- if [ $delete -eq 1 ]; then
- /usr/lib/lpadmin -x$nam > /dev/null 2>&1
- fi
-
- # Unconditionally remove the Impressario stuff. If we're replacing
- # an Impressario printer with a non-Impressario printer, we need to
- # do this to make sure all the extra stuff gets removed.
- #
- remove_impressario
-
- ####
- # Make sure all relevant directories are available
- ####
- create_support_dirs
-
- /usr/lib/print/instnetpr $type $host $printer $nam
- rc=$?
- if [ $rc != 0 ]; then
- exit $rc
- fi
- ####
- # Enable the printer
- ####
- enable $nam > /dev/null 2>&1
- /usr/lib/accept $nam > /dev/null 2>&1
- selectSoloPrinterAsDefault
- ;;
- replace|add)
- delete=1
- if [ "$1" = "replace" ]; then
- delete=0
- fi
- #
- # Add a new printer
- #
- # add <dev> <model> <name> [OPT=xxx ...]
- #
- # where:
- #
- # <dev> is the pathname to the device
- # <model> is the name of the model script to use
- # <name> is the name the new printer will have
- # OPT=xxx is a model modifier in which "OPT="
- # lines in model are changed to "OPT=xxx".
- # Multiple OPT= can be specified.
- #
- dev=$2
- mod=$3
- nam=$4
- shift;shift;shift;shift
- ERRNOMOD="No such printer model as \"$mod\"."
- ERRNODEV="Unable to write to device \"$dev\"."
- ERRNONAM="No printer name was specified."
- ERRLOGIN="Logins are currently enabled on this port."
- ERRMODEM="A modem is currently enabled on this port."
-
- # Check for existence of printer model.
- #
- if [ ! -r "model/${mod}" ]; then
- echo $ERRNOMOD 1>&2
- exit 1
- fi
-
- # Check the ~lp/devices is created if needed.
- # Some printer drivers use this and the higher level
- # install utility is supposed to create this directory.
- # Check here in case future drivers do not (easy to miss
- # since most developers systems would have it and would
- # assume it is a standard lp sub-dir -- it is not).
- # Defensive programming.
-
- DIRNAME=`dirname $dev`
- if [ "$DIRNAME" = "/var/spool/lp/devices" ] ; then
- if [ ! -d /var/spool/lp/devices ] ; then
- mkdir /var/spool/lp/devices
- chmod 0755 /var/spool/lp/devices
- chown lp.sys /var/spool/lp/devices
- fi
- if [ ! -c $dev ] ; then
- mknod $dev c 1 2
- chmod 0666 $dev
- chown lp.sys $dev
- fi
- fi
-
- # Verify that device is there.
- #
- if [ ! -w $dev ]; then
- echo $ERRNODEV 1>&2
- exit 1
- fi
-
- # Make sure there's a name for the new printer.
- #
- if [ -z "$nam" ]; then
- echo $ERRNONAM 1>&2
- exit 1
- fi
-
- # Check for gettys or modems enabled if the device
- # is a serial port.
- #
- if expr X"$dev" : ".*tty" > /dev/null; then
- # Watch out for ttyd1 vs. ttym1 vs. ttyf1 etc.
- #
- ttynum=`expr X"$dev" : ".*tty[dmf]\([0-9]*\)"`
- re="tty[dmf]$ttynum[^0-9]"
- if who -l | grep $re > /dev/null; then
- echo $ERRLOGIN 1>&2
- exit 1
- fi
- ml=`grep "^[^#].*$re" /usr/lib/uucp/Devices 2> /dev/null`
- if [ -n "$ml" ]; then
- echo $ERRMODEM 1>&2
- exit 1
- fi
- fi
-
- # Give exclusive control of device to lp
- #
- if [ "$dev" != "/dev/null" ]; then
- chown lp $dev
- chmod 0600 $dev
- # For 6.4+ update /etc/ioperms file (see ioconfig(1M))
- $SETDEVPERMS -a "$dev 0600 lp sys"
- fi
-
- # Assemble substitution arguments so they can be done in
- # one sed command.
-
- for i
- do
- lhs=`expr "$i" : "\(.*\)="`
- if [ -n "$lhs" ]; then
- sc="${sc}-e 's@^${lhs}=.*@${i}@' "
- fi
- done
-
- # Strip out " (Impressario license required)" if found so it
- # is not in the final name. /usr/lib/print/modelinfo may add it.
-
- sc=`echo $sc | sed 's/ (Impressario license required)//'`;
-
- # See if we have a PPD model file. Have to do a couple special
- # steps for the PPD model driver. We set it here so lower
- # level functions can use it. Any ~lp/model file with the
- # string "impressario_ppd_model" in the name is treated as
- # a impressario PPD driver.
-
- test_ppd=""
- HAVE_PPD=0
- test_ppd=`echo $mod | awk '/impressario_ppd_model/'`;
- if [ "$test_ppd" != "" ]; then
- HAVE_PPD=1
- fi
-
- if [ "$HAVE_PPD" = "1" ]; then
- # See if this is a 3 or 4 color device being supported
- # and set the global flag accordingly. NUM_PPD_COLORS
- # is used later
- test_ppd=`echo $* | awk '/numcolors=3/'`;
- if [ "$test_ppd" != "" ]; then
- NUM_PPD_COLORS=3
- fi
- test_ppd=`echo $* | awk '/numcolors=4/'`;
- if [ "$test_ppd" != "" ]; then
- NUM_PPD_COLORS=4
- fi
- fi
-
- if [ -z "$sc" ]; then
- cp model/${mod} /tmp/$nam
- else
- # recursive quoting in $sc requires this nastiness
- #
- sh -c "sed $sc model/${mod} > /tmp/$nam"
- fi
-
- # We don't want any partial adds
- #
- trap '' 1 2 3 15
-
- # Install or replace the printer. Installing a printer
- # overwrites any printer or class with the same name. It is
- # the caller's responsibility to check for duplicate names.
- #
- # Replacing a printer changes the device and model for a
- # printer, but doesn't blow away the queue.
- #
- if [ $delete -eq 1 ]; then
- /usr/lib/lpadmin -x$nam > /dev/null 2>&1
- fi
-
- # Unconditionally remove the Impressario stuff. If we're replacing
- # an Impressario printer with a non-Impressario printer, we need to
- # do this to make sure all the extra stuff gets removed.
- #
- remove_impressario
-
- /usr/lib/lpadmin -p$nam -v$dev -i/tmp/$nam
- rc=$?
- rm -f /tmp/$nam
- if [ $rc != 0 ]; then
- remove_printer $nam # No partial printers!!
- exit 1
- fi
- df=`cat $SPOOL_DIR/default 2> /dev/null`
- if [ -z "$df" ]; then
- /usr/lib/lpadmin -d$nam
- fi
- enable $nam > /dev/null 2>&1
-
- # Enable the printer
- #
- /usr/lib/accept $nam > /dev/null 2>&1
- selectSoloPrinterAsDefault
-
- # Install all the Impressario support
- #
- RTYPE=`egrep "^TYPE=" $SPOOL_DIR/interface/$nam`
- rt="`echo "$RTYPE" | sed 's/TYPE=//'`"
- RHOST=`egrep "^HOSTNAME=" $SPOOL_DIR/interface/$nam`
- rh="`echo "$RHOST" | sed 's/HOSTNAME=//'`"
- RPRTR=`egrep "^HOSTPRINTER=" $SPOOL_DIR/interface/$nam`
- rp="`echo "$RPRTR" | sed 's/HOSTPRINTER=//'`"
-
- PPDNAME=`egrep "^ppdname=" $SPOOL_DIR/interface/$nam`
- ppd_name="`echo "$PPDNAME" | sed 's/ppdname=//'`"
-
- #
- # Always call this routine last, it has side effects
- #
- install_impressario
- exit 0
- ;;
- remove)
- #
- # lputil remove <printer or class> <move dest>
- #
- # remove a printer after optionally moving all of its
- # outstanding requests to another destination.
- #
- nam=$2
- mvdest=$3
- if [ -z "$nam" ]; then
- echo "No printer name was specified to delete." 1>&2
- exit 2
- fi
-
- # We don't want any partial deletes
- #
- trap '' 1 2 3 15
-
- # Close off both ends of the print queue
- #
- /usr/lib/reject -r"*deletion in progress*" $nam > /dev/null 2>&1
- disable -c -r"*deletion in progress*" $nam > /dev/null 2>&1
-
- # Move queue if needed
- #
- if [ -n "$mvdest" ]; then
- /usr/lib/lpmove $nam $mvdest > /dev/null 2>&1
- fi
-
- remove_printer $nam
- exit 0
- ;;
- chkremote)
- #
- # lputil chkremote <machine> <remote login id>
- #
- # chkremote will list the printers on a remote host.
- #
- if /sbin/chkconfig network; then
- :
- else
- echo "Networking has not been enabled on this system." 1>&2
- exit 1
- fi
- if [ -z "$2" ]; then
- echo "No remote hostname was specified for chkremote." 1>&2
- exit 2
- fi
-
- /usr/lib/print/listprinters -a $2 2>/dev/null
- rcexit
- exit 0
- ;;
- remoteinfo)
- #
- # lputil remoteinfo <machine> <printer> <login id>
- #
- # Get the information associated with a printer located
- # on a remote machine.
- #
- if [ -z "$4" ]; then
- REMOTE_LOGIN_ID=lp
- else
- REMOTE_LOGIN_ID=$4
- fi
- NAME=
- TYPE=
- HOSTNAME=
- HOSTPRINTER=
- BAUDRATE=
- STTYPARAMS=
- eval `rsh $2 -n -l $REMOTE_LOGIN_ID \
- "/bin/sh -c \"/usr/lib/lputil getinfo $3\"" 2>/dev/null` \
- 2> /dev/null 1>&2 0<&1
-
- # If we don't come up with all of the keywords, we can
- # try to guess on some.
- #
- if [ -z "$TYPE" ]; then
- ps=`rsh $2 -n -l $REMOTE_LOGIN_ID \
- "/bin/sh -c \"grep PostScript \
- $OLD_SPOOL_DIR/interface/$3 2>/dev/null\""`
- if [ -n "$ps" ]; then
- NAME="LaserWriter"
- TYPE=PostScript
- else
- color=`rsh $2 -n -l $REMOTE_LOGIN_ID \
- "/bin/sh -c \"grep 'color printer' \
- $OLD_SPOOL_DIR/interface/$3 2>/dev/null\""`
- if [ -n "$color" ]; then
- NAME="Color Printer"
- TYPE=Color
- fi
- fi
- fi
- if [ -z "$HOSTNAME" -a -n "$host" ]; then
- HOSTNAME=$host
- fi
- if [ -z "$HOSTPRINTER" -a -n "$printer" ]; then
- HOSTPRINTER=$printer
- fi
- echo NAME=\"$NAME\"
- echo TYPE=$TYPE
- echo HOSTNAME=$HOSTNAME
- echo HOSTPRINTER=$HOSTPRINTER
- echo BAUDRATE=$BAUDRATE
- echo STTYPARAMS=$STTYPARAMS
- exit 0
- ;;
- printq)
- #
- # lputil printq <machine> <printer> <login id>
- #
- # printq will return the lpstat information from
- # a local or remote print queue
- #
- if [ -z "$2" -o "`hostname`" = "$2" ]; then
- /usr/bin/lpstat -o$3 2> /dev/null 2>&1
- exit 3
- fi
- if [ -z "$4" ]; then
- REMOTE_LOGIN_ID=lp
- else
- REMOTE_LOGIN_ID=$4
- fi
- if /sbin/chkconfig network; then
- :
- else
- echo "Networking has not been enabled on this system." 1>&2
- exit 1
- fi
- rsh $2 -n -l $REMOTE_LOGIN_ID \
- "/bin/sh -c \"/usr/bin/lpstat -o$3 2> /dev/null\"" 2>&1
- exit $?
- ;;
- *)
- echo "lputil: invalid operation - $*" 1>&2
- exit 2
- ;;
- esac
-
- #
- # Return a successful exit code
- #
- exit 0
-